#include "stdafx.h"
#include "curl_event_loop.h"
#include "curl_ctx.h"

namespace async_curl {
	void curl_ctx::poll_cb(uv_poll_t* handle, int status, int events) {
		auto *ins = static_cast<curl_ctx*>(handle->data);
		auto curl_flags = int(0);
		if (events&UV_READABLE) {
			curl_flags |= CURL_CSELECT_IN;
		}
		if (events&UV_WRITABLE) {
			curl_flags |= CURL_CSELECT_OUT;
		}
		auto nhandles = 0;
		curl_multi_socket_action(ins->mgr_->curlm_, ins->sock_fd_, curl_flags, &nhandles);
		ins->mgr_->check_curl_tasklist();
	}

	void curl_ctx::stop_cb(uv_handle_t * handle) {
		auto* ctx = static_cast<curl_ctx*>(handle->data);
		delete ctx;
	}

	curl_ctx::curl_ctx(curl_event_loop* mgr, curl_socket_t fd) :
		mgr_(mgr),
		sock_fd_(fd),
		poll_(new uv_poll_t),
		counter_(mgr->get_refcounter()) {
		uv_poll_init_socket(mgr_->loop_, poll_, sock_fd_);
		poll_->data = this;
		curl_multi_assign(mgr_->curlm_, sock_fd_, this);
	}

	curl_ctx::~curl_ctx() {
		delete poll_;
	}

	void curl_ctx::chpoll(int evt) {
		uv_poll_start(poll_, evt, &curl_ctx::poll_cb);
	}

	void curl_ctx::stop() {
		uv_poll_stop(poll_);
		uv_close((uv_handle_t*)poll_, &curl_ctx::stop_cb);
		curl_multi_assign(mgr_->curlm_, sock_fd_, nullptr);
	}
}
